home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / indents.zip / lexi.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  22KB  |  597 lines

  1. /**
  2.  * Copyright (c) 1985 Sun Microsystems, Inc.
  3.  * Copyright (c) 1980 The Regents of the University of California.
  4.  * Copyright (c) 1976 Board of Trustees of the University of Illinois.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted provided
  8.  * that the above copyright notice and this paragraph are duplicated in all
  9.  * such forms and that any documentation, advertising materials, and other
  10.  * materials related to such distribution and use acknowledge that the
  11.  * software was developed by the University of California, Berkeley, the
  12.  * University of Illinois, Urbana, and Sun Microsystems, Inc.  The name of
  13.  * either University or Sun Microsystems may not be used to endorse or
  14.  * promote products derived from this software without specific prior written
  15.  * permission. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES
  17.  * OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #include "globals.h"
  21. #include "codes.h"
  22.  
  23. #ifndef lint
  24. # ifndef ANSIC
  25. static char     sccsid[] = "@(#)lexi.c    6.0 (Berkeley) 92/06/15";
  26. # endif         /* ANSIC */
  27. #endif          /* not lint */
  28.  
  29. /* Here we have the token scanner for indent.  It scans off one token and
  30.  * puts it in the global variable "token".  It returns a code, indicating the
  31.  * type of token scanned. */
  32.  
  33. #include <ctype.h>
  34. #include <string.h>
  35.  
  36. typedef enum char_type {
  37.     alphanum = 1,
  38.     opchar = 3,
  39.     colonchar = 4
  40. } char_type;
  41.  
  42. struct templ {
  43.     char           *rwd;
  44.     int             rwcode;
  45.     cplus_flag      cplus;
  46. };
  47.  
  48. struct templ    specials[100] =
  49. {
  50.     {"switch", 1, c_and_cplus},
  51.     {"case", 2, c_and_cplus},
  52.     {"break", 0, c_and_cplus},
  53.     {"struct", 3, c_and_cplus},
  54.     {"union", 3, c_and_cplus},
  55.     {"enum", 3, c_and_cplus},
  56.     {"default", 2, c_and_cplus},
  57.     {"int", 4, c_and_cplus},
  58.     {"char", 4, c_and_cplus},
  59.     {"float", 4, c_and_cplus},
  60.     {"double", 4, c_and_cplus},
  61.     {"long", 4, c_and_cplus},
  62.     {"short", 4, c_and_cplus},
  63.     {"typedef", 8, c_and_cplus},
  64.     {"unsigned", 4, c_and_cplus},
  65.     {"register", 4, c_and_cplus},
  66.     {"static", 4, c_and_cplus},
  67.     {"global", 4, c_and_cplus},
  68.     {"extern", 4, c_and_cplus},
  69.     {"void", 4, c_and_cplus},
  70.     {"goto", 0, c_and_cplus},
  71.     {"return", 0, c_and_cplus},
  72.     {"if", 5, c_and_cplus},
  73.     {"while", 5, c_and_cplus},
  74.     {"for", 5, c_and_cplus},
  75.     {"else", 6, c_and_cplus},
  76.     {"do", 6, c_and_cplus},
  77.     {"sizeof", 7, c_and_cplus},
  78.     {"class", 3, cplus_only},
  79.     {"public", 2, cplus_only},
  80.     {"private", 2, cplus_only},
  81.     {"protected", 2, cplus_only},
  82.     {"volatile", 4, c_and_cplus},
  83.     {0, 0}
  84. };
  85.  
  86. char            chartype[128] =
  87. {                               /* this is used to facilitate the decision of
  88.                                  * what type (alphanumeric, operator) each
  89.                                  * character is */
  90.     0, 0, 0, 0, 0, 0, 0, 0,
  91.     0, 0, 0, 0, 0, 0, 0, 0,
  92.     0, 0, 0, 0, 0, 0, 0, 0,
  93.     0, 0, 0, 0, 0, 0, 0, 0,
  94.     0, 3, 0, 0, 1, 3, 3, 0,
  95.     0, 0, 3, 3, 0, 3, 0, 3,
  96.     1, 1, 1, 1, 1, 1, 1, 1,
  97.     1, 1, 4, 0, 3, 3, 3, 3,
  98.     0, 1, 1, 1, 1, 1, 1, 1,
  99.     1, 1, 1, 1, 1, 1, 1, 1,
  100.     1, 1, 1, 1, 1, 1, 1, 1,
  101.     1, 1, 1, 0, 0, 0, 3, 1,
  102.     0, 1, 1, 1, 1, 1, 1, 1,
  103.     1, 1, 1, 1, 1, 1, 1, 1,
  104.     1, 1, 1, 1, 1, 1, 1, 1,
  105.     1, 1, 1, 0, 3, 0, 3, 0
  106. };
  107.  
  108.  
  109.  
  110. #ifdef ANSIC
  111. int             lexi(void)
  112. #else           /* ANSIC */
  113. int             lexi()
  114. #endif          /* ANSIC */
  115. {
  116.     register char  *tok = NULL; /* local pointer to next char in token */
  117.     int             unary_delim;/* this is set to 1 if the current token
  118.                                  * 
  119.                                  * forces a following operator to be unary */
  120.     static int      last_code = 0;  /* the last token type returned */
  121.     static int      l_struct = 0;   /* set to 1 if the last token was
  122.                                      * 'struct' */
  123.     static int      l_struct_start = 0; /* set at struct, cleared at { or ; */
  124.     static int      l_class = 0;/* in c++, class name coming next. */
  125.     int             code;       /* internal code to be returned */
  126.     char            qchar;      /* the delimiter character for a string */
  127.  
  128.     tok = token;                /* point to start of place to save token */
  129.     unary_delim = false;
  130.     ps.col_1 = ps.last_nl;      /* tell world that this token started in
  131.                                  * column 1 iff the last thing scanned was a
  132.                                  * newline */
  133.     ps.last_nl = false;
  134.  
  135.     while (*buf_ptr == ' ' || *buf_ptr == '\t') {   /* get rid of blanks */
  136.         ps.col_1 = false;       /* leading blanks imply token is not in
  137.                                  * column 1 */
  138.         if (++buf_ptr >= buf_end)
  139.             fill_buffer();
  140.     }
  141.  
  142.     /* Scan an alphanumeric token */
  143.     /* In c++, :: starting token is OK, as is ~ sometimes */
  144.     /* well, int x = ~y; will work oddly here */
  145.     if (((char_type) chartype[*buf_ptr] == alphanum || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) ||
  146.         (cplus && buf_ptr[0] == ':' && buf_ptr[1] == ':') ||
  147.         (cplus && ps.in_decl && *buf_ptr == '~'
  148.          && (char_type) chartype[buf_ptr[1]] == alphanum)   /* destructors in
  149.                                                              * classdefs */
  150.         ) {
  151.         /* we have a character or number */
  152.         register char  *j = NULL;   /* used for searching through list of
  153.                                      * reserved words */
  154.         register struct templ *p;
  155.  
  156.         if (isdigit(*buf_ptr) || buf_ptr[0] == '.' && isdigit(buf_ptr[1])) {
  157.             int             seendot = 0,
  158.                             seenexp = 0;
  159.  
  160.             if (*buf_ptr == '0' &&
  161.                 (buf_ptr[1] == 'x' || buf_ptr[1] == 'X')) {
  162.                 *tok++ = *buf_ptr++;
  163.                 *tok++ = *buf_ptr++;
  164.                 while (isxdigit(*buf_ptr))
  165.                     *tok++ = *buf_ptr++;
  166.             } else
  167.                 while (1) {
  168.                     if (*buf_ptr == '.')
  169.                         if (seendot)
  170.                             break;
  171.                         else
  172.                             seendot++;
  173.                     *tok++ = *buf_ptr++;
  174.                     if (!isdigit(*buf_ptr) && *buf_ptr != '.')
  175.                         if ((*buf_ptr != 'E' && *buf_ptr != 'e') || seenexp)
  176.                             break;
  177.                         else {
  178.                             seenexp++;
  179.                             seendot++;
  180.                             *tok++ = *buf_ptr++;
  181.                             if (*buf_ptr == '+' || *buf_ptr == '-')
  182.                                 *tok++ = *buf_ptr++;
  183.                         }
  184.                 }
  185.             if (*buf_ptr == 'L' || *buf_ptr == 'l')
  186.                 *tok++ = *buf_ptr++;
  187.         } else {
  188.             int             first;
  189.  
  190.             first = 1;
  191.             while ((char_type) chartype[*buf_ptr] == alphanum ||
  192.                    (buf_ptr[0] == ':' && buf_ptr[1] == ':' && cplus) ||
  193.                    (cplus && first && buf_ptr[0] == '~')) { /* copy it over */
  194.                 int             colonp;
  195.  
  196.                 first = 0;
  197.                 colonp = *buf_ptr == ':';
  198.                 *tok++ = *buf_ptr++;
  199.                 if (colonp) {
  200.                     *tok++ = *buf_ptr++;
  201.                     /* foo::~foo */
  202.                     if (*buf_ptr == '~')
  203.                         *tok++ = *buf_ptr++;
  204.                     colonp = 0;
  205.                 }
  206.                 if (buf_ptr >= buf_end)
  207.                     fill_buffer();
  208.             }
  209.         }
  210.         *tok++ = '\0';
  211.         while (*buf_ptr == ' ' || *buf_ptr == '\t') {   /* get rid of blanks */
  212.             if (++buf_ptr >= buf_end)
  213.                 fill_buffer();
  214.         }
  215.         ps.its_a_keyword = false;
  216.         ps.sizeof_keyword = false;
  217.         if (l_struct) {         /* if last token was 'struct', then this
  218.